home *** CD-ROM | disk | FTP | other *** search
- Path: vixen.cso.uiuc.edu!usenet
- From: homer@uiuc.edu
- Newsgroups: comp.lang.c++
- Subject: Re: Virtual Base Class
- Date: 14 Mar 1996 05:43:54 GMT
- Organization: University of Illinois at Urbana
- Message-ID: <4i8bmq$qu0@vixen.cso.uiuc.edu>
- References: <313F98D0.102E@ucla.edu> <4i1k92$3n8@apoll.informatik.uni-bonn.de> <31472DB0.511A@ucla.edu>
- Reply-To: n-dade@uiuc.edu
- NNTP-Posting-Host: homer.apr.uiuc.edu
- X-Newsreader: IBM NewsReader/2 v1.2
-
-
- schregle@Mars (Roland Schregle) suggests this flithy code:
-
- >void f()
- >{
- > a a1;
- > d* testy = new d; // :)
- > int offset = (void*)testy - (void*)(a*)testy;
- > delete testy;
- > d* pd = (d*)((void*)a1 + offset);
- >}
-
- Yes that will do the trick, and yes it is filthy!
- I have a slightly (only slightly) more elegant solution
- to this problem.
-
- My trick is to use a virtual function that returns the
- this pointer in each final derived class. That way once
- I know that my A* is really a D* I can cast the output
- that function to D*. I often make that function protected
- and add conversion operators in the base class so that
- I cannot forget and convert the void* returned by that
- function to any old class*.
-
- If you don't feel safe with the operator (since it does
- allow automatic conversion from A to D*) you can replace
- the operator with a named function.
-
- Here's a little example:
-
-
- #include <iostream.h>
-
- class D;
-
- class A {
- protected:
- virtual void* QueryThis() = 0; // returns void* to
- // avoid any automatic
- // conversions by the
- // compiler; is not
- // "const" so I don't
- // have to return
- // "const void*"
- public:
- // I wish I could use this to convert A to D& but
- // the compiler does choke on that. So I convert
- // A to D* instead.
- operator D* () { return (D*) QueryThis(); }
- };
-
- class B : virtual public A {};
- class C : virtual public A {};
-
- class D : public B, public C {
- private:
- int i;
- protected:
- void* QueryThis() { return this; } // fill out virtual
- // function in final
- // derived class so
- // that (D*) operator
- // in A can get the
- // value of D::this
- public:
- D(int ii) : i(ii) {}
- void sayhi() const { cout << "Hi, I'm #" << i << endl; }
- };
-
- main() {
- D d(12345); // create a D
- A* a = &d; // get a pointer to its base class A
- D* p = *a; // convert the A back to a D*
- p->sayhi(); // a test to see if the pointer is any good
-
- return 0;
- }
-
-
-